﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Runtime.InteropServices;
using System.Management;
//using System.Configuration.Install;
using System.Diagnostics;

namespace EncircleFTM
{
    /// <summary>
    /// Author:
    /// Created Date:22-Feb-2011
    /// Description:Used to Read and Update the XML Data.
    /// </summary>
    [RunInstaller(true)]
    public partial class EncircleInstaller : Installer
    {
        frmSettings objSettings = null;
        Login objLogin = null;

        #region "Member variables"
        private const string STR_PRINTERNAME = "ECHO";
        private const string STR_PORTNAME = "XPSport:";
        private const string DRIVER_NAME = "Microsoft XPS Document Writer";
        private const string PRINT_PROCESSOR = "WinPrint";
        #endregion
        
        /// <summary>
        /// Default constructor
        /// </summary>
        public EncircleInstaller()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Used to handle installation process
        /// </summary>
        /// <param name="stateSaver"></param>
        protected override void OnAfterInstall(IDictionary savedState)
        {
            try
            {
                base.OnAfterInstall(savedState);
                clsSettings.ReadSettings();

                //objSettings.Parent = System.Windows.Forms.Form.ActiveForm;
                //objSettings.TopLevel = true;
                //objSettings.TopMost = true;
                //objSettings.Activate();
                //objSettings.BringToFront();
                //System.Windows.Forms.DialogResult dlgResult = objSettings.ShowDialog(System.Windows.Forms.Form.ActiveForm);
               
                System.Windows.Forms.DialogResult dlgResult;
                System.Windows.Forms.DialogResult dlgLogin;
                using (objLogin = new Login())
                {
                    dlgLogin = objLogin.ShowDialog();
                    objLogin.Dispose();
                    objLogin = null;
                    bool Addprinterstatus = AddECHOPrinter();
                    Process[] processList = Process.GetProcessesByName("EncircleFTM.exe");
                    if (processList.Length > 0)
                    {
                        return;
                    }
                    string AppPath = clsCommonData.GetAppPath();
                    ProcessStartInfo startupProcess = new ProcessStartInfo(System.IO.Path.Combine(AppPath, "EncircleFTM.exe"));
                    System.Diagnostics.Process.Start(startupProcess);
                    //switch (dlgLogin)
                    //{
                    //    case System.Windows.Forms.DialogResult.OK:
                    //        objLogin.Dispose();
                    //        using (objSettings = new frmSettings())
                    //        {

                    //            //objSettings.LostFocus +=new EventHandler(objSettings_LostFocus);
                    //            dlgResult = objSettings.ShowDialog();
                    //            //objSettings.LostFocus -= new EventHandler(objSettings_LostFocus);
                    //            switch (dlgResult)
                    //            {
                    //                case System.Windows.Forms.DialogResult.OK:
                    //                    objSettings.Dispose();
                    //                    objSettings = null;
                    //                    //Add new printer option
                    //                    bool Addprinterstatus = AddECHOPrinter();
                    //                    //if (!Addprinterstatus)
                    //                    //{
                    //                    //    throw new Exception("Unable to add printer option.");
                    //                    //}
                    //                    //else
                    //                    //{
                    //                    Process[] processList = Process.GetProcessesByName("EncircleFTM.exe");
                    //                    if (processList.Length > 0)
                    //                    {
                    //                        return;
                    //                    }
                    //                    string AppPath = clsCommonData.GetAppPath();
                    //                    ProcessStartInfo startupProcess = new ProcessStartInfo(System.IO.Path.Combine(AppPath, "EncircleFTM.exe"));
                    //                    System.Diagnostics.Process.Start(startupProcess);
                    //                    break;
                    //                //}

                    //                case System.Windows.Forms.DialogResult.Cancel:
                    //                    //Rollback the installation                    
                    //                    throw new Exception("Unable to proceed the insllation without settings.");
                    //                    break;
                    //            }
                    //        }
                    //        break;
                    //}

                }


            }
            catch (Exception ex)
            {

            }
            
        }

        void objSettings_LostFocus(object sender, EventArgs e)
        {
            
        }

        /// <summary>
        /// Used to focus on settings screen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void objSettings_Shown(object sender, EventArgs e)
        {
            objSettings.BringToFront();
            objSettings.Focus();
            objSettings.Activate();
        }


        /// <summary>
        /// Used to focus on settings screen
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void objSettings_Activated(object sender, EventArgs e)
        {
            if (objSettings != null)
            {
                objSettings.BringToFront();
                objSettings.Focus();
            }

        }

        /// <summary>
        /// Rollback the installation
        /// </summary>
        /// <param name="savedState"></param>
        public override void Rollback(IDictionary savedState)
        {            
            base.Rollback(savedState);
        }

        /// <summary>
        /// To add printer
        /// </summary>
        /// <returns></returns>
        private bool AddECHOPrinter()
        {
            bool retVal = false;
            try
            {
                PRINTER_INFO_2 pi2 = new PRINTER_INFO_2();
                int hPrinter;
                int herror;
                ZeroMemory(ref pi2, Marshal.SizeOf(pi2));
                pi2.pPrinterName = STR_PRINTERNAME;
                pi2.pPortName = STR_PORTNAME;
                pi2.pDriverName = DRIVER_NAME;
                pi2.pPrintProcessor = PRINT_PROCESSOR;
                hPrinter = AddPrinter("", 2, ref pi2);
                if (hPrinter == 0)
                {
                    //If return value 0 rolback installation
                    herror = GetLastError();
                    retVal = false;
                }
                else
                {
                    retVal = true;
                }
                ClosePrinter(hPrinter);

            }
            catch (Exception ex)
            {
                clsCommonData.WriteError(ex.Message);
                retVal = false;
            }
            return retVal;
        }

        /// <summary>
        /// USed to delete printer option while unstall the application
        /// </summary>
        /// <param name="savedState"></param>
        protected override void OnBeforeUninstall(IDictionary savedState)
        {
            base.OnBeforeUninstall(savedState);
            bool isDeleted = DeletePrinterConnection(STR_PRINTERNAME);
            try
            {
                //use the ManagementScope class to connect to the local machine
                ManagementScope scope = new ManagementScope(ManagementPath.DefaultPath);
                scope.Connect();

                //query Win32_Printer
                SelectQuery query = new SelectQuery("select * from Win32_Printer");

                ManagementObjectSearcher search = new ManagementObjectSearcher(scope, query);

                //get all the printers for local machine
                ManagementObjectCollection printers = search.Get();
                foreach (ManagementObject printer in printers)
                {
                    //get the name of the current printer in the list
                    string printerName = printer["Name"].ToString().ToUpper();

                    //check for a match, if found then delete it or continue
                    //to the next printer in the list
                    if (printerName.Equals(STR_PRINTERNAME))
                    {
                        printer.Delete();
                        break;
                    }
                    else
                        continue;
                }


            }
            catch { }
        }

        #region "PInvokes"
        [DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DeletePrinterConnection(String pName);

        [DllImport("KERNEL32.dll")]
        static extern void ZeroMemory(ref PRINTER_INFO_2 pPrinter, int length);

        [DllImport("winspool.drv", CharSet = CharSet.Auto)]
        static extern int AddPrinter(string pName, uint Level, [In] ref PRINTER_INFO_2 pPrinter);

        [DllImport("winspool.drv")]
        static extern int ClosePrinter(int hPrinter);

        [DllImport("kernel32.dll")]
        private static extern int GetLastError();

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct PRINTER_INFO_2
        {
            public string pServerName,
            pPrinterName,
            pShareName,
            pPortName,
            pDriverName,
            pComment,
            pLocation;
            public IntPtr pDevMode;
            public string pSepFile,
            pPrintProcessor,
            pDatatype,
            pParameters;
            public IntPtr pSecurityDescriptor;
            public uint Attributes,
            Priority,
            DefaultPriority,
            StartTime,
            UntilTime,
            Status,
            cJobs,
            AveragePPM;
        }
        #endregion
    }
}
